namespace Plugins.Engine
{
    using System;
    using Plugins.Interfaces;
    using Plugins.Serializer;

    [Serializable]
    public class PluginOptions :
        IPluginOptions, 
        IPluginPersistent<string>, 
        IPluginConstructible<PluginOptions>,
        IPluginSerializable
    {
        private PluginPropertyContainer _properties = new PluginPropertyContainer();
        private readonly IPluginFileSerializer<PluginOptions> _serializer = new PluginFileSerializer<PluginOptions>();
        private static readonly IPluginRuntimeFormatter Formatter = new XmlFormatter();
        private static readonly IPluginStringSerializer<PluginOptions> XmlSerializer = new PluginUnicodeStringSerializer<PluginOptions>();

        public void Initialize(PluginOptions obj)
        {
            if (obj != null)
            {
                this._properties.Initialize(obj.Items);
                Update();
            }
        }

        public bool Load(string store)
        {
            if (this._serializer.Deserialize(store, Formatter))
            {
                this.Initialize(this._serializer.RuntimeObject);
                return true;
            }
            return false;
        }
        public bool Save(string store)
        {
            if (this._serializer.Serialize(store, this, Formatter))
            {
                return true;
            }
            return false;
        }

        public string Serialize()
        {
            return XmlSerializer.Serialize(this, Formatter);
        }

        public void Update()
        {
            _properties.UpdateProperties();
        }

        public IPluginPropertyContainer Items
        {
            get
            {
                return this._properties;
            }
        }

        public PluginPropertyContainer Options
        {
            get
            {
                return this._properties;
            }
            set
            {
                this._properties = value;
            }
        }

        private class XmlFormatter : PluginTypeSerializer<PluginOptions>
        {
            public override void AddOverrides(IPluginTypeFormatter formatter)
            {
                base.AddType(formatter, "options");
                base.AddElement(formatter, "Options", "collection", typeof(PluginPropertyContainer));
                PluginPropertyContainer.Formatter.AddOverrides(formatter);
            }
        }

        #region IPluginOptions Members

        public void AddEvent(string propertyName, Action<IPluginProperty> propertyHandler)
        {
            _properties.AddEvent(propertyName, propertyHandler);
        }

        public void AddEvent(string propertyName, Action<IPluginProperty> propertyHandler, int priority)
        {
            _properties.AddEvent(propertyName, propertyHandler, priority);
        }

        public void RemoveEvent(string propertyName, Action<IPluginProperty> propertyHandler)
        {
            _properties.RemoveEvent(propertyName, propertyHandler);
        }

        public void RemoveEvent(string propertyName, Action<IPluginProperty> propertyHandler, int priority)
        {
            _properties.RemoveEvent(propertyName, propertyHandler);
        }

        #endregion
    }
}

